package wps.component.elementsetting {

import flash.events.FocusEvent;

import mx.core.FlexBitmap;
import mx.events.FlexEvent;
import mx.formatters.NumberBase;

import spark.components.TextInput;
import spark.formatters.NumberFormatter;

import wps.util.StringUtils;

/**
 * 如果是数字输入模式，可设置输入范围，是否只能输入整数或浮点数<br/>
 * 当焦点在输入框内，按下回车或失去焦点时，认为输入完成<br/>
 * 如果在输入完成后需要进行额外操作，可覆盖inputComplete方法
 */
public class SettingTextInputBase extends TextInput {

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    // inputComplete
    //----------------------------------

    private var _inputComplete:Boolean;

    /**
     * 输入结束后设置为true。失去焦点时，如果已经按过回车键，避免重复调用输入完成的方法
     */
    public function get inputComplete():Boolean {
        return _inputComplete;
    }

    public function set inputComplete(inputComplete:Boolean):void {
        _inputComplete = inputComplete;
    }

    //----------------------------------
    // numericOnly
    //----------------------------------

    private var _numericOnly:Boolean;

    [Inspectable(category = "General", defaultValue = "true")]
    /**
     * true只能输入数字，小数精度为2
     */
    public function get numericOnly():Boolean {
        return _numericOnly;
    }

    public function set numericOnly(numericOnly:Boolean):void {
        if (numericOnly && integerOnly) {
            integerOnly = false;
        }

        _numericOnly = numericOnly;
        restrict = numericOnly ? "0-9\\-\\." : null;
    }

    //----------------------------------
    // integerOnly
    //----------------------------------

    private var _integerOnly:Boolean;

    [Inspectable(category = "General", defaultValue = "true")]
    /**
     * true只能输入整数
     */
    public function get integerOnly():Boolean {
        return _integerOnly;
    }

    public function set integerOnly(integerOnly:Boolean):void {
        if (integerOnly && numericOnly) {
            numericOnly = false;
        }

        _integerOnly = integerOnly;
        restrict = integerOnly ? "0-9\\-" : null;
    }

    //----------------------------------
    // minValue
    //----------------------------------

    private var _minValue:Number;

    /**
     * 可输入的最小值，只在数字输入模式下有效
     */
    public function get minValue():Number {
        return _minValue;
    }

    public function set minValue(minValue:Number):void {
        _minValue = minValue;
    }

    //----------------------------------
    // maxValue
    //----------------------------------

    private var _maxValue:Number;

    /**
     * 可输入的最大值，只在数字输入模式下有效
     */
    public function get maxValue():Number {
        return _maxValue;
    }

    public function set maxValue(maxValue:Number):void {
        _maxValue = maxValue;
    }

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    public function SettingTextInputBase() {
        super();

        // 按回车键或焦点移出输入框时表示输入结束
        addEventListener(FlexEvent.ENTER, enterHandler);
        addEventListener(FlexEvent.INITIALIZE, initializeHandler);
    }

    //--------------------------------------------------------------------------
    //
    // Methods
    //
    //--------------------------------------------------------------------------

    override protected function focusInHandler(e:FocusEvent):void {
        super.focusInHandler(e);

        inputComplete = false;
    }

    /**
     * 输入完成后的操作
     */
    protected function inputCompleted():void {
        // textInput控件默认截取到两位小数，不做四舍五入
        if (numericOnly || integerOnly) {
            if (StringUtils.isBlank(text)) {
                return;
            }

            var num:Number = Number(text);

            // 虽然设置了restrict，但是还可以输入5-6这样的字符串
            // 这种情况下取"-"符号前的数字
            if (isNaN(num) && text && text.length > 0) {
                text = text.substring(0, text.indexOf("-"));
                num = Number(text);
            }

            if (!isNaN(minValue)) {
                num = Math.max(num, minValue);
            }
            if (!isNaN(maxValue)) {
                num = Math.min(num, maxValue);
            }
            text = num.toString();
        }
    }

    private function setMaxChars():void {
        var max:Number;

        if (maxValue && minValue) {
            max = Math.max(Math.abs(maxValue), Math.abs(minValue));
        }

        if (max) {
            // 获取整数部分的字符个数
            var intlen:Number;
            var dotIndex:int = max.toString().indexOf(".");
            if (dotIndex > -1) {
                intlen = max.toString().substring(0, dotIndex).length;
            } else {
                intlen = max.toString().length;
            }

            if (numericOnly) {
                // 加上小数点，两位小数，负号
                maxChars = intlen + 4;
            }
            if (integerOnly) {
                // 加上负号
                maxChars = intlen + 1;
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    // Event handlers
    //
    //--------------------------------------------------------------------------

    protected function initializeHandler(e:FlexEvent):void {
        if (numericOnly || integerOnly) {
            setMaxChars();
        }
    }

    protected function enterHandler(e:FlexEvent):void {
        inputCompleted();
        inputComplete = true;
    }

    override protected function focusOutHandler(e:FocusEvent):void {
        super.focusOutHandler(e);

        // 如果在失去焦点时已经按过回车建完成输入，不做操作
        if (!inputComplete) {
            inputCompleted();
        }
    }

    override public function set text(value:String):void {
        if (integerOnly) {
            if (StringUtils.isNotBlank(text)) {
                var num:Number = Number(value);
                value = Math.round(num).toString();
            }
        }
        super.text = value;
    }

}

}
